/*
 * All content copyright http://www.j2eefast.com, unless
 * otherwise indicated. All rights reserved.
 * No deletion without permission
 */
package com.j2eefast.framework.config;

import cn.hutool.core.comparator.ComparableComparator;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.setting.Setting;
import com.j2eefast.common.core.utils.ToolUtil;
import com.j2eefast.common.db.context.DataSourceContext;
import com.j2eefast.common.db.utils.SqlExe;
import com.j2eefast.framework.sys.entity.SysModuleEntity;
import com.j2eefast.framework.sys.service.SysModuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.List;

/**
 * @author huanzhou
 * @date 2024/2/28
 */
@Slf4j
@Component
public class UpdateDbScript implements ServletContextListener {

    @Autowired
    private SysModuleService sysModuleService;
    /**
     * 是否检测脚本自动升级
     */
    @Value("#{ @environment['fast.updateDb.auto'] ?: false }")
    private boolean auto;

    private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("检验系统升级脚本....");
        /**
         * 初始化检测模块
         */
        List<SysModuleEntity> list = sysModuleService.list();
        for(SysModuleEntity entity: list){
            boolean flag = true;
            try {
                Class.forName(entity.getMainClassName());
            }catch (ClassNotFoundException e){
                flag = false;
            }
            if(!flag){
                if(!entity.getStatus().equals("2")){
                    entity.setStatus("2");
                    sysModuleService.setRoles(entity.getId(), entity.getStatus());
                }
            }else{

                if(!entity.getStatus().equals("0")){
                    entity.setStatus("0");
                    sysModuleService.setRoles(entity.getId(), entity.getStatus());
                }

                // 根据不同模块进行数据库升级
                if(auto){
                    try{
                        Resource[] resources = resourceResolver.getResources("classpath*:/config"+
                                "/update/db/" +entity.getModuleCode() + "/version.setting");
                        //检测升级脚本
                        if(ToolUtil.isNotEmpty(resources)){
                            log.info("version file: '"+resources[0]+"'");
                            Setting setting = new Setting(resources[0].getURL(), CharsetUtil.CHARSET_UTF_8,false);
                            if(!setting.isEmpty("dbType") && !setting.isEmpty("version")){
                                //指定数据库
                                String dbType = setting.get("dbType","dbName");
                                if(ToolUtil.isNotEmpty(dbType)){
                                    //数据库版本
                                    String dbV = entity.getCurrentVersion();
                                    //获取本身系统对应数据库类型
                                    String defaultDbType = DataSourceContext.getDbType(dbType);
                                    if(ToolUtil.isEmpty(defaultDbType)){
                                        continue;
                                    }
                                    String update_info = "";
                                    for(int i=1;;i++){
                                        if(setting.containsKey("version","v"+i)){
                                            String tempVersion = setting.get("version","v"+i);
                                            if(ToolUtil.isNotEmpty(tempVersion)){
                                                if(ComparableComparator.INSTANCE.compare(dbV,tempVersion) < 0){
                                                    //需要脚本升级 检测脚本数据库对应脚本是否存在
//                                                path = "classpath:config"+File.separator+"update"+File.separator+"db"+ File.separator + entity.getModuleCode() +
//                                                        File.separator + defaultDbType + File.separator  + defaultDbType+"_" +tempVersion + ".sql";
                                                    resources = resourceResolver.getResources("classpath*:/config/update/db/"+entity.getModuleCode() +
                                                            "/" + defaultDbType + "/"+ tempVersion + ".sql");
                                                    if(ToolUtil.isNotEmpty(resources)){
                                                        //
                                                        log.info("-----------------------<{}>模块 -->[版本:{} 升级-->{}]----------------------",
                                                                entity.getModuleName(),dbV,tempVersion);
                                                        SqlExe.runFileSql(dbType,resources[0]);
                                                        update_info = "更新时间:" + DateUtil.now() + " 版本:"+entity.getCurrentVersion() +" --> " +tempVersion;
                                                        dbV = tempVersion;
                                                    }
                                                }
                                            }
                                        }else{
                                            break;
                                        }
                                    }

                                    if(ToolUtil.isNotEmpty(update_info) && !entity.getCurrentVersion().equals(dbV)){
                                        sysModuleService.setVersion(entity.getId(),dbV,update_info);
                                    }
                                }
                            }
                        }
                    }catch (Exception e){
                    }
                }
            }
        }
    }
}
